#include "stm32f10x.h"
#include "system.h"
#include "Hardware_stm32f10x.h"
#include "typedef.h"



static volatile bool systick_enable = false;		        // SysTick使能标志
static volatile uint32_t critical_nesting = 0;		        // 临界区嵌套计数器


/****************************************************************************************************
 @name	u32 SYS_GetSysClock(void)

 @brief  获取当前系统总线时间

 @param  	DevClock]	选择外设设备
					[Enable]	使能

 @return void

 @notes

****************************************************************************************************/

u32 SYS_GetSysClock(void)
{
    return 0;
}
/****************************************************************************************************
 @name	void SYS_PeripheralClockEnable(SYS_DEV_CLOCKTypeDef DevClock,bool Enable)

 @brief  系统时钟使能

 @param  [DevClock]	选择外设设备
					[Enable]	使能

 @return void

 @notes

****************************************************************************************************/
void SYS_PeripheralClockEnable(SYS_DEV_CLOCKTypeDef DevClock,bool Enable)
{
//	const __IO uint32_t * const RCC_FCG[]={&APB1PERIPH_BASE,&APB2PERIPH_BASE};	//就两个时钟管理
    u8 n = DevClock >> 8; 		//选择哪一个时钟总线
    u8 bit = DevClock & 0xFF;	//使能外设位

    if(bit > MAX_BIT) return ;	//越界无效
    if(n >=MAX_APBNUM) return; 	//越界无效

    switch(n){
        case 0: //APB1
        {
            if(Enable == true) RCC->APB1ENR |= (1 <<bit);
            else RCC->APB1ENR &= ~(1 <<bit);
            break;
        }
        case 1: //APB2
        {
            if(Enable == true) RCC->APB2ENR |= (1 <<bit);
            else   RCC->APB2ENR &= ~(1 <<bit);
            break;
        }
    }
}



/****************************************************************************************************
 @name	void SYS_RESET(void)

 @brief  系统复位

 @param  void

 @return void

 @notes

****************************************************************************************************/
void SYS_RESET(void)
{
    __set_FAULTMASK(1);
    NVIC_SystemReset();
}


/****************************************************************************************************
 @brief  进入临界区，支持嵌套

 @param  无

 @return 无
****************************************************************************************************/
void cpu_enter_critical(void)
{
    if(critical_nesting < UINT32_MAX)
    {
        critical_nesting++;
        if(critical_nesting == 1) {		// 第一次进入临界区
            __disable_irq();
        }
    }
}


/****************************************************************************************************
 @brief  退出临界区

 @param  无

 @return 无
****************************************************************************************************/
void cpu_exit_critical(void)
{
    if(critical_nesting > 0)
    {
        critical_nesting--;
        if(critical_nesting == 0) {		// 最后一次退出临界区
            __enable_irq();
        }
    }
}


/****************************************************************************************************
 @name	void SYS_GPIOx_PinInit(GPIO_TypeDef *GPIOx,u8 PinNum,SYS_GPIO_MODE Mode,SYS_GPIO_DRV GPIO_DRV_Gain,GPIO_PinStatus Status)

 @brief

 @param  [GPIOx]GPIO端口 	GPIOA GPIOB GPIOC GPIOD GPIOE
		 [PinNum] 			GPIO0~GPIO15
		 [Mode]				GPIO工作模式
		 [GPIO_DRV_Gain]	GPIO驱动能力
		 [GPIO_PinStatus]	GPIO的工作状态：上拉,下拉,浮空
 @return void

 @notes

****************************************************************************************************/
void SYS_GPIOx_PinInit(GPIO_TypeDef *GPIOx, uint8_t PinNum, SYS_GPIO_MODE Mode, SYS_GPIO_DRV GPIO_DRV_Gain, GPIO_PinStatus Status) {
    volatile uint32_t *config_reg;
    uint32_t pin_offset;

    // 确定配置寄存器（CRL/CRH）和偏移量
    if (PinNum < 8) {
        config_reg = &GPIOx->CRL;
        pin_offset = PinNum * 4; // 每个引脚占4位
    } else {
        config_reg = &GPIOx->CRH;
        pin_offset = (PinNum - 8) * 4;
    }

    uint32_t temp = *config_reg;
    temp &= ~(0x0F << pin_offset); // 清除原有配置

    // 配置模式与速度
    uint32_t cnf_mode = 0;
    switch (Mode) {
        case GPIO_MODE_INPUT:
            if (Status == GPIO_PIN_PULLUP || Status == GPIO_PIN_PULLDOWN) {
                cnf_mode |= BIT8; // 上拉/下拉输入
            } else if (Status == GPIO_PIN_FLOATING) {
                cnf_mode |= BIT2; // 浮空输入
            } else {
                cnf_mode = (0x00 << 2); // 模拟输入
            }
            break;
        case GPIO_MODE_OUTPUT_PP:
            cnf_mode = (0x00  << 2) | GPIO_DRV_Gain;
            break;
        case GPIO_MODE_OUTPUT_OD:
            cnf_mode = (0x01 << 2) | GPIO_DRV_Gain;
            break;
        case GPIO_MODE_AF_PP:
            cnf_mode = (0x02 << 2) | GPIO_DRV_Gain;
            break;
        case GPIO_MODE_AF_OD:
            cnf_mode = (0x04 << 2) | GPIO_DRV_Gain;
            break;
        case GPIO_MODE_ANALOG:
            cnf_mode = (0x00<< 2); // 模拟模式
            break;
        default:
            return; // 错误处理
    }

    temp |= (cnf_mode << pin_offset);
    *config_reg = temp;

    // 设置上拉/下拉或初始电平
    if (Mode == GPIO_MODE_INPUT) {
        if (Status == GPIO_PIN_PULLUP) {
            GPIOx->ODR |= (1 << PinNum);
        } else if (Status == GPIO_PIN_PULLDOWN) {
            GPIOx->ODR &= ~(1 << PinNum);
        }
    } else {
        if (Status == GPIO_PIN_PULLUP) {
            GPIOx->ODR |= (1 << PinNum); // 输出高
        } else if (Status == GPIO_PIN_PULLDOWN) {
            GPIOx->ODR &= ~(1 << PinNum); // 输出低
        }
    }
}



#if 0
void SYS_GPIOx_PinInit(GPIO_TypeDef *GPIOx,u8 PinNum,SYS_GPIO_MODE Mode,SYS_GPIO_DRV GPIO_DRV_Gain,GPIO_PinStatus Status)
{
	uint32_t pinpos;
    uint32_t pos;
    uint32_t currentmode;
    __IO uint32_t *configregister;
    uint32_t registeroffset;

    /* 参数有效性检查 */
    if (PinNum > 15) return;

    /* 配置模式寄存器选择（CRL/CRH） */
    configregister = (PinNum < 8) ? &GPIOx->CRL : &GPIOx->CRH;	//0~7使用CRL 8~15使用CRH
    registeroffset = (PinNum < 8) ? (PinNum << 2) : ((PinNum - 8) << 2);

    /* 清除原有配置 */
    *configregister &= ~(0x0F << registeroffset);

    /* 设置驱动能力 */
    uint32_t mode_bits;
    switch (GPIO_DRV_Gain) {
        case GPIO_Low_Drv: mode_bits = 0x02; break;  // 2MHz (01b)
        case GPIO_Mid_Drv: mode_bits = 0x01; break;  // 10MHz (01b)
        case GPIO_High_Drv: mode_bits = 0x03; break;  // 50MHz (11b)
        default: mode_bits = 0x00; break;
    }

    /* 配置工作模式 */
    uint32_t cnf_bits;
    switch (Mode) {
        case OUT_PP:         // 推挽输出
            cnf_bits = 0x00;
            currentmode = (mode_bits << 2) | cnf_bits;
            break;

        case OUT_OD:         // 开漏输出
            cnf_bits = 0x04;
            currentmode = (mode_bits << 2) | cnf_bits;
            break;

        case IN_FLOATING:    // 浮空输入
            cnf_bits = 0x04;
            currentmode = cnf_bits;
            break;

        case IN_IPU:         // 上拉输入
            cnf_bits = 0x08;
            currentmode = cnf_bits;
            GPIOx->BSRR = (1 << PinNum);  // 设置上拉
            break;

        case IN_AIN:         // 模拟输入
            cnf_bits = 0x00;
            currentmode = cnf_bits;
            break;

        default:
            return;
    }

    /* 写入配置寄存器 */
    *configregister |= (currentmode << registeroffset);

    /* 特殊处理模拟输入模式 */
    if (Mode == IN_AIN) {
        GPIOx->CRL &= ~(0x03 << registeroffset);  // 确保MODE=00
        GPIOx->CRL |= (0x00 << registeroffset);    // CNF=00
    }

}
#endif

